<template>
  <div class="container">
    <div class="flex items-center justify-between mb-6">
      <div>
        <h1 class="page-title">操作日志</h1>
        <p class="text-gray-500">记录系统操作，便于追溯和审计</p>
      </div>
      <el-button type="danger" @click="confirmClearLogs">
        <el-icon class="mr-1"><Delete /></el-icon>清空日志
      </el-button>
    </div>
    
    <el-card shadow="hover" class="mb-6">
      <div class="search-container">
        <el-date-picker
          v-model="dateRange"
          type="daterange"
          range-separator="至"
          start-placeholder="开始日期"
          end-placeholder="结束日期"
          :shortcuts="dateShortcuts"
          value-format="YYYY-MM-DD"
          @change="handleDateChange"
          style="width: 340px"
        />
        <el-select 
          v-model="operationType" 
          placeholder="操作类型" 
          clearable 
          @change="loadLogs"
          style="width: 160px"
        >
          <el-option label="全部" value="" />
          <el-option label="登录" value="login" />
          <el-option label="新增" value="create" />
          <el-option label="修改" value="update" />
          <el-option label="删除" value="delete" />
          <el-option label="导出" value="export" />
        </el-select>
        <el-input
          v-model="searchQuery"
          placeholder="请输入用户名或操作内容"
          prefix-icon="Search"
          clearable
          @clear="loadLogs"
          @input="debounceSearch"
          style="width: 240px"
        />
        <div>
          <el-button type="primary" @click="loadLogs" :loading="loading">查询</el-button>
          <el-button @click="resetQuery">重置</el-button>
        </div>
      </div>
    </el-card>
    
    <el-card shadow="hover" class="overflow-hidden">
      <el-table 
        :data="logList" 
        border 
        stripe 
        style="width: 100%"
        v-loading="loading"
        :header-cell-class-name="'bg-gray-100 dark:bg-gray-700'"
      >
        <el-table-column prop="id" label="ID" width="80" align="center" />
        <el-table-column prop="username" label="操作用户" width="120" />
        <el-table-column prop="type" label="操作类型" width="100" align="center">
          <template #default="scope">
            <el-tag :type="getOperationTypeTag(scope.row.type)" effect="light" class="status-tag">
              {{ getOperationTypeName(scope.row.type) }}
            </el-tag>
          </template>
        </el-table-column>
        <el-table-column prop="module" label="操作模块" width="120" />
        <el-table-column prop="description" label="操作内容" min-width="250" show-overflow-tooltip />
        <el-table-column prop="ipAddress" label="IP地址" width="150" />
        <el-table-column prop="userAgent" label="浏览器" width="180" show-overflow-tooltip />
        <el-table-column prop="createTime" label="操作时间" width="180" />
        <el-table-column prop="status" label="状态" width="100" align="center">
          <template #default="scope">
            <el-tag :type="scope.row.status === 1 ? 'success' : 'danger'" effect="light" class="status-tag">
              {{ scope.row.status === 1 ? '成功' : '失败' }}
            </el-tag>
          </template>
        </el-table-column>
        <el-table-column label="操作" width="120" fixed="right" align="center">
          <template #default="scope">
            <el-button type="primary" size="small" @click="viewLogDetail(scope.row)">详情</el-button>
          </template>
        </el-table-column>
      </el-table>
      
      <div class="pagination-container">
        <el-pagination
          v-model:current-page="currentPage"
          v-model:page-size="pageSize"
          :page-sizes="[10, 20, 50, 100]"
          layout="total, sizes, prev, pager, next, jumper"
          :total="total"
          @size-change="handleSizeChange"
          @current-change="handleCurrentChange"
          background
        />
      </div>
    </el-card>
    
    <!-- 日志详情对话框 -->
    <el-dialog
      v-model="dialogVisible"
      title="日志详情"
      width="700px"
      destroy-on-close
    >
      <div v-if="selectedLog" class="log-detail">
        <div class="grid grid-cols-1 md:grid-cols-2 gap-4 mb-6">
          <div class="log-detail-item">
            <p class="log-detail-label">ID</p>
            <p class="log-detail-value">{{ selectedLog.id }}</p>
          </div>
          <div class="log-detail-item">
            <p class="log-detail-label">操作用户</p>
            <p class="log-detail-value">{{ selectedLog.username }}</p>
          </div>
          <div class="log-detail-item">
            <p class="log-detail-label">操作类型</p>
            <p class="log-detail-value">
              <el-tag :type="getOperationTypeTag(selectedLog.type)" effect="light" class="status-tag">
                {{ getOperationTypeName(selectedLog.type) }}
              </el-tag>
            </p>
          </div>
          <div class="log-detail-item">
            <p class="log-detail-label">操作模块</p>
            <p class="log-detail-value">{{ selectedLog.module }}</p>
          </div>
          <div class="log-detail-item">
            <p class="log-detail-label">操作状态</p>
            <p class="log-detail-value">
              <el-tag :type="selectedLog.status === 1 ? 'success' : 'danger'" effect="light" class="status-tag">
                {{ selectedLog.status === 1 ? '成功' : '失败' }}
              </el-tag>
            </p>
          </div>
          <div class="log-detail-item">
            <p class="log-detail-label">操作时间</p>
            <p class="log-detail-value">{{ selectedLog.createTime }}</p>
          </div>
          <div class="log-detail-item">
            <p class="log-detail-label">IP地址</p>
            <p class="log-detail-value">{{ selectedLog.ipAddress }}</p>
          </div>
          <div class="log-detail-item">
            <p class="log-detail-label">浏览器</p>
            <p class="log-detail-value">{{ selectedLog.userAgent }}</p>
          </div>
        </div>
        
        <div class="log-detail-item mb-6">
          <p class="log-detail-label">操作内容</p>
          <p class="log-detail-value whitespace-pre-wrap">{{ selectedLog.description }}</p>
        </div>
        
        <div v-if="selectedLog.requestParams" class="log-detail-item mb-6">
          <p class="log-detail-label">请求参数</p>
          <el-input
            type="textarea"
            :value="formatJson(selectedLog.requestParams)"
            autosize
            readonly
            class="log-code-area"
          />
        </div>
        
        <div v-if="selectedLog.errorMessage" class="log-detail-item">
          <p class="log-detail-label">错误信息</p>
          <el-input
            type="textarea"
            :value="selectedLog.errorMessage"
            autosize
            readonly
            class="log-error-area"
          />
        </div>
      </div>
    </el-dialog>
  </div>
</template>

<script>
import { ref, onMounted } from 'vue'
import { ElMessage, ElMessageBox } from 'element-plus'
import { Delete } from '@element-plus/icons-vue'
import axios from 'axios'

export default {
  name: 'LogsView',
  components: {
    Delete
  },
  setup() {
    // 日志列表数据
    const logList = ref([])
    const currentPage = ref(1)
    const pageSize = ref(20)
    const total = ref(0)
    const dateRange = ref([])
    const operationType = ref('')
    const searchQuery = ref('')
    const loading = ref(false)
    
    // 日志详情
    const dialogVisible = ref(false)
    const selectedLog = ref(null)
    
    // 日期快捷选项
    const dateShortcuts = [
      {
        text: '最近一周',
        value: () => {
          const end = new Date()
          const start = new Date()
          start.setTime(start.getTime() - 3600 * 1000 * 24 * 7)
          return [start, end]
        },
      },
      {
        text: '最近一个月',
        value: () => {
          const end = new Date()
          const start = new Date()
          start.setTime(start.getTime() - 3600 * 1000 * 24 * 30)
          return [start, end]
        },
      },
      {
        text: '最近三个月',
        value: () => {
          const end = new Date()
          const start = new Date()
          start.setTime(start.getTime() - 3600 * 1000 * 24 * 90)
          return [start, end]
        },
      },
    ]
    
    // 初始化
    onMounted(() => {
      // 初始化日期范围为近一周
      const end = new Date()
      const start = new Date()
      start.setTime(start.getTime() - 3600 * 1000 * 24 * 7)
      dateRange.value = [formatDate(start), formatDate(end)]
      
      loadLogs()
    })
    
    // 防抖搜索
    let searchTimeout = null
    const debounceSearch = () => {
      if (searchTimeout) {
        clearTimeout(searchTimeout)
      }
      searchTimeout = setTimeout(() => {
        loadLogs()
      }, 500)
    }
    
    // 重置查询条件
    const resetQuery = () => {
      searchQuery.value = ''
      operationType.value = ''
      // 保留日期范围
      loadLogs()
    }
    
    // 加载日志数据
    const loadLogs = async () => {
      loading.value = true
      try {
        // 实际项目中应从API获取
        /*
        const params = {
          page: currentPage.value,
          size: pageSize.value,
          startDate: dateRange.value[0],
          endDate: dateRange.value[1],
          type: operationType.value,
          query: searchQuery.value
        }
        const response = await axios.get('/api/logs', { params })
        logList.value = response.data.list
        total.value = response.data.total
        */
        
        // 模拟数据延迟
        await new Promise(resolve => setTimeout(resolve, 500))
        
        // 模拟数据
        const mockLogs = [
          {
            id: 1001,
            username: 'admin',
            type: 'login',
            module: '系统',
            description: '用户登录',
            ipAddress: '192.168.1.100',
            userAgent: 'Chrome 96.0.4664.110',
            createTime: '2023-06-20 08:30:15',
            status: 1,
            requestParams: JSON.stringify({
              username: 'admin',
              timestamp: '2023-06-20 08:30:15'
            }),
            errorMessage: null
          },
          {
            id: 1002,
            username: 'zhangsan',
            type: 'create',
            module: '车辆信息',
            description: '新增车辆信息: 京A12345',
            ipAddress: '192.168.1.101',
            userAgent: 'Chrome 96.0.4664.110',
            createTime: '2023-06-20 09:15:22',
            status: 1,
            requestParams: JSON.stringify({
              vehicleNo: '京A12345',
              brand: '丰田',
              model: '卡罗拉',
              engineNo: 'ENG123456',
              frameNo: 'FRM123456',
              buyDate: '2022-01-10'
            }),
            errorMessage: null
          },
          {
            id: 1003,
            username: 'lisi',
            type: 'update',
            module: '驾驶员信息',
            description: '修改驾驶员信息: 李四',
            ipAddress: '192.168.1.102',
            userAgent: 'Firefox 95.0',
            createTime: '2023-06-20 10:05:30',
            status: 1,
            requestParams: JSON.stringify({
              id: 2,
              name: '李四',
              phone: '13800138002',
              drivingLicense: 'DL987654321',
              status: 1
            }),
            errorMessage: null
          },
          {
            id: 1004,
            username: 'wangwu',
            type: 'delete',
            module: '加油卡信息',
            description: '删除加油卡信息: 123456789',
            ipAddress: '192.168.1.103',
            userAgent: 'Chrome 97.0.4692.71',
            createTime: '2023-06-20 11:22:18',
            status: 0,
            requestParams: JSON.stringify({
              id: 5,
              cardNo: '123456789'
            }),
            errorMessage: '系统错误: 该加油卡仍有关联的车辆，无法删除'
          },
          {
            id: 1005,
            username: 'admin',
            type: 'export',
            module: '报表',
            description: '导出车辆使用分析报表',
            ipAddress: '192.168.1.100',
            userAgent: 'Chrome 96.0.4664.110',
            createTime: '2023-06-20 14:10:45',
            status: 1,
            requestParams: JSON.stringify({
              startDate: '2023-01-01',
              endDate: '2023-06-20',
              vehicleId: null
            }),
            errorMessage: null
          }
        ]
        
        // 过滤日志
        let filteredLogs = [...mockLogs]
        
        if (searchQuery.value) {
          const query = searchQuery.value.toLowerCase()
          filteredLogs = filteredLogs.filter(log => 
            log.username.toLowerCase().includes(query) || 
            log.description.toLowerCase().includes(query)
          )
        }
        
        if (operationType.value) {
          filteredLogs = filteredLogs.filter(log => log.type === operationType.value)
        }
        
        logList.value = filteredLogs
        total.value = filteredLogs.length
      } catch (error) {
        ElMessage.error('获取日志列表失败')
        console.error('获取日志列表失败:', error)
      } finally {
        loading.value = false
      }
    }
    
    // 查看日志详情
    const viewLogDetail = (log) => {
      selectedLog.value = log
      dialogVisible.value = true
    }
    
    // 确认清空日志
    const confirmClearLogs = () => {
      ElMessageBox.confirm(
        '确定要清空所有操作日志吗？此操作将不可恢复！',
        '警告',
        {
          confirmButtonText: '确定',
          cancelButtonText: '取消',
          type: 'warning'
        }
      ).then(() => {
        clearLogs()
      }).catch(() => {
        // 用户取消操作
      })
    }
    
    // 清空日志
    const clearLogs = async () => {
      loading.value = true
      try {
        // 实际项目中应调用API
        /*
        await axios.delete('/api/logs/clear')
        */
        
        // 模拟API延迟
        await new Promise(resolve => setTimeout(resolve, 500))
        
        // 模拟API调用
        logList.value = []
        total.value = 0
        ElMessage.success('已成功清空所有操作日志')
      } catch (error) {
        ElMessage.error('清空日志失败')
        console.error('清空日志失败:', error)
      } finally {
        loading.value = false
      }
    }
    
    // 处理日期变化
    const handleDateChange = () => {
      loadLogs()
    }
    
    // 处理页面大小变化
    const handleSizeChange = (val) => {
      pageSize.value = val
      loadLogs()
    }
    
    // 处理页码变化
    const handleCurrentChange = (val) => {
      currentPage.value = val
      loadLogs()
    }
    
    // 获取操作类型名称
    const getOperationTypeName = (type) => {
      const types = {
        login: '登录',
        create: '新增',
        update: '修改',
        delete: '删除',
        export: '导出'
      }
      return types[type] || type
    }
    
    // 获取操作类型标签类型
    const getOperationTypeTag = (type) => {
      const types = {
        login: 'info',
        create: 'success',
        update: 'warning',
        delete: 'danger',
        export: 'primary'
      }
      return types[type] || ''
    }
    
    // 格式化JSON
    const formatJson = (jsonString) => {
      try {
        return JSON.stringify(JSON.parse(jsonString), null, 2)
      } catch (e) {
        return jsonString
      }
    }
    
    // 日期格式化
    const formatDate = (date) => {
      const year = date.getFullYear()
      const month = String(date.getMonth() + 1).padStart(2, '0')
      const day = String(date.getDate()).padStart(2, '0')
      return `${year}-${month}-${day}`
    }
    
    return {
      logList,
      currentPage,
      pageSize,
      total,
      dateRange,
      dateShortcuts,
      operationType,
      searchQuery,
      loading,
      dialogVisible,
      selectedLog,
      loadLogs,
      handleDateChange,
      handleSizeChange,
      handleCurrentChange,
      viewLogDetail,
      confirmClearLogs,
      getOperationTypeName,
      getOperationTypeTag,
      resetQuery,
      debounceSearch,
      formatJson
    }
  }
}
</script>

<style scoped>
.log-detail-item {
  margin-bottom: var(--space-sm);
}

.log-detail-label {
  color: var(--text-secondary);
  font-size: 14px;
  margin-bottom: 4px;
}

.log-detail-value {
  font-weight: 500;
  color: var(--text-color);
}

.log-code-area :deep(.el-textarea__inner) {
  font-family: monospace;
  background-color: var(--bg-color);
  padding: 12px;
  border-radius: 6px;
  font-size: 13px;
}

.log-error-area :deep(.el-textarea__inner) {
  font-family: monospace;
  background-color: rgba(239, 68, 68, 0.05);
  color: var(--danger-color);
  padding: 12px;
  border-radius: 6px;
  font-size: 13px;
}

.dark-theme .log-code-area :deep(.el-textarea__inner) {
  background-color: rgba(255, 255, 255, 0.05);
}

.dark-theme .log-error-area :deep(.el-textarea__inner) {
  background-color: rgba(239, 68, 68, 0.15);
}
</style> 